package emulator;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import emulator.shell.GUI.util.DialogBase;

@SuppressWarnings("serial")
public class VicSetupDialog extends DialogBase
{
	static Logger logger = LogManager.getLogger(VicSetupDialog.class.getName());

	public final static int VIC20 = 0;
	public final static int VIC1541 = 1;
	
	private int systemIndex = VIC20;
	private EmulatorConfig emulatorConfig = new EmulatorConfig();
	
	private JCheckBox selectIecSimulation;
	private JCheckBox selectFe3Support;
	private JCheckBox selectPortStateLogging;
	
	public VicSetupDialog(JFrame owner)
	{
		super(owner, "Setup Emulator", true);
		buildContents();
		pack();
		setLocationRelativeTo(null);
	}
	
	public EmulatorConfig getEmulatorConfig()
	{
		return emulatorConfig;
	}

	public int getSystemIndex()
	{
		return systemIndex;
	}

	private void buildContents()
	{
		JComboBox selectSystem = new JComboBox(new String [] { "Vic-20", "Vic-1541 (experimental)" });
		selectSystem.addActionListener(new SystemSelectListener());
		selectSystem.setAlignmentX(0);
		selectSystem.setToolTipText(
				"<html>" +
				"<b>Select the system you want to run.</b><br><br>" +
				"<i>Note: VIC-1541 Emulation is experimental and does not emulate the hardware yet</i>"+
				"</html>"
				);
		selectPortStateLogging = new JCheckBox("Log port state (slow)");
		selectPortStateLogging.setAlignmentX(0);
		selectPortStateLogging.setToolTipText(
				"<html>" +
				"<b>Enables logging for VIA I/O</b><br><br>" +
				"This option enables logging of I/O states for both VIAs and " +
				"extends the VIA state window by a graph showing the logged values.<br>" +
				"<i>Note: Port state logging slows down emulation by ~25%</i>" +
				"</html>"
				);
		selectIecSimulation = new JCheckBox("IEC device simulation");
		selectIecSimulation.setAlignmentX(0);
		selectIecSimulation.setToolTipText(
				"<html>" +
				"<b>Enables a simple emulation for IEC devices</b><br><br>" +
				"The IEC simulator emulates the communication protocol of Commodore's serial bus." +
				"At present, the emulator supports two devices:" +
				"<ul>" +
				"<li><i>Printer</i> is like a null device that \"consumes\" every byte and discards it immediately.</li>" +
				"<li><i>Disk</i> is a file system driver that supports reading files (including \"$\") from the local file system.</li>" +
				"</ul>" +
				"</html>"
				);
		selectFe3Support = new JCheckBox("FE3 RAM support");
		selectFe3Support.setAlignmentX(0);
		selectFe3Support.setToolTipText(
				"<html>" +
				"<b>Enables support for the Super RAM mode of the Final Epansion 3</b><br><br>" +
				"Super RAM mode is fully supported by the emulation. Although the debugger is not aware of the extra RAM,<br>" +
				"you can always view and edit all RAM Banks of the Final expansion in the memory window." +
				"</html>"
				);
		
		JPanel panelOptions = new JPanel();
		panelOptions.setLayout(new BoxLayout(panelOptions, BoxLayout.PAGE_AXIS));
		panelOptions.add(selectSystem);
		panelOptions.add(selectIecSimulation);
		panelOptions.add(selectFe3Support);
		panelOptions.add(selectPortStateLogging);
		
		getContentPane().setLayout(new BorderLayout());
		
		getContentPane().add(panelOptions, BorderLayout.CENTER);
		getContentPane().add(createButtonPanel(), BorderLayout.PAGE_END);
	}

	private void updateDialogState()
	{
		selectIecSimulation.setEnabled(systemIndex == VIC20);
		selectFe3Support.setEnabled(systemIndex == VIC20);
	}
	
	@Override
	protected void closeDialog(boolean result)
	{
		if (result)
		{
			emulatorConfig.setEnableFe3Support(selectFe3Support.isSelected());
			emulatorConfig.setEnableIecSimulation(selectIecSimulation.isSelected());
			emulatorConfig.setEnablePortLogging(selectPortStateLogging.isSelected());
		}
		super.closeDialog(result);
	}

	public class SystemSelectListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e)
		{
			JComboBox selectSystem = (JComboBox)e.getSource();
			systemIndex = selectSystem.getSelectedIndex();
			updateDialogState();
		}
	}
	
	/**
	 * @param args
	 * @throws IOException 
	 * @throws FileNotFoundException 
	 */
	public static void main(String[] args) throws FileNotFoundException, IOException
	{
		try {
			UIManager.setLookAndFeel(
					UIManager.getSystemLookAndFeelClassName());
		} catch (Exception ex)
		{
			logger.error("Failed to set system look & feel.", ex);
		}
		VicSetupDialog setupDialog = new VicSetupDialog(null);
		setupDialog.setVisible(true);
		if (setupDialog.getResult())
		{
			switch (setupDialog.getSystemIndex())
			{
			case VIC20:
				VicMain.runEmulator(args, setupDialog.getEmulatorConfig());
				break;
			case VIC1541:
				Vc1541Main.runEmulator(args, setupDialog.getEmulatorConfig());
				break;
			default:
				JOptionPane.showMessageDialog(null, "System configuration " + setupDialog.getSystemIndex() + " is not valid!", "Error running emulator", JOptionPane.ERROR_MESSAGE);
				break;
			}
		}
	}
}
